<script setup lang="ts">
import type { FormInst, FormItemRule, FormRules, UploadFileInfo } from 'naive-ui'
import { addDeviceType, updateDeviceType, uploadProtocol } from '@/service/api/deviceType'
import PropertyManagerModal from './PropertyManagerModal.vue'
import NovaIcon from '@/components/common/NovaIcon.vue'

defineOptions({ name: 'DeviceTypeModal' })

interface Props {
  visible: boolean
  type: 'add' | 'edit'
  modalData: Api.DeviceType.Info | null
  availableDrivers: string[]
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  type: 'add',
  modalData: null,
  availableDrivers: () => [],
})

interface Emits {
  (e: 'update:visible', visible: boolean): void
  (e: 'success'): void
}

const emit = defineEmits<Emits>()

const formRef = ref<FormInst | null>(null)

const formData = ref<Api.DeviceType.AddRequest>({
  name: '',
  driver: '',
  properties: [],
})

const rules: FormRules = {
  name: [
    { required: true, message: '请输入设备类型名称', trigger: 'blur' },
  ],
}

const isUploading = ref(false)
const fileList = ref<UploadFileInfo[]>([])
const propertyManagerVisible = ref(false)

watch(
  [() => props.visible, () => props.modalData, () => props.type],
  ([visible, data, type]) => {
    if (visible && data && type === 'edit') {
      formData.value = {
        name: data.name,
        driver: data.driver || '',
        properties: data.properties || [],
      }
    }
    else if (visible && type === 'add') {
      resetForm()
    }
  },
  { immediate: true },
)

function openPropertyManager() {
  propertyManagerVisible.value = true
}

function handlePropertiesUpdate(properties: Api.DeviceType.Property[]) {
  formData.value.properties = properties
}

function resetForm() {
  formData.value = {
    name: '',
    driver: '',
    properties: [],
  }
  fileList.value = []
}

function closeModal() {
  emit('update:visible', false)
}

async function handleSubmit() {
  await formRef.value?.validate()

  try {
    if (props.type === 'add') {
      const { isSuccess } = await addDeviceType(formData.value)
      if (isSuccess) {
        window.$message.success('添加成功')
        emit('success')
        closeModal()
      }
    }
    else {
      const { isSuccess } = await updateDeviceType(formData.value)
      if (isSuccess) {
        window.$message.success('更新成功')
        emit('success')
        closeModal()
      }
    }
  }
  catch (e: any) {
    window.$message.error(e.message || '操作失败')
  }
}

// 上传协议包
async function handleUploadProtocol({ file }: { file: UploadFileInfo }) {
  if (!formData.value.name) {
    window.$message.error('请先填写设备类型名称')
    return
  }

  isUploading.value = true
  try {
    const { isSuccess, data } = await uploadProtocol(formData.value.name, file.file as File)
    if (isSuccess && data) {
      window.$message.success('上传成功')
      // 更新驱动和属性信息
      formData.value.driver = data.driver || ''
      formData.value.properties = data.properties || []
    }
  }
  catch (e: any) {
    window.$message.error(e.message || '上传失败')
  }
  finally {
    isUploading.value = false
    fileList.value = []
  }
}
</script>

<template>
  <NModal
    v-model:show="props.visible"
    :title="type === 'add' ? '新建设备类型' : '编辑设备类型'"
    preset="card"
    class="w-700px"
    @after-leave="resetForm"
  >
    <NForm
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-placement="left"
      label-width="100"
      require-mark-placement="left"
    >
      <NFormItem label="类型名称" path="name">
        <NInput
          v-model:value="formData.name"
          placeholder="请输入设备类型名称（英文标识）"
          :disabled="type === 'edit'"
        />
      </NFormItem>

      <NFormItem label="协议/驱动" path="driver">
        <NSelect
          v-model:value="formData.driver"
          :options="availableDrivers.map(d => ({ label: d, value: d }))"
          placeholder="请选择协议"
          clearable
          filterable
          tag
        />
      </NFormItem>

      <NFormItem label="上传协议包">
        <NSpace vertical class="w-full">
          <NUpload
            v-model:file-list="fileList"
            accept=".zip"
            :max="1"
            :show-file-list="false"
            :custom-request="handleUploadProtocol"
          >
            <NButton :loading="isUploading" secondary>
              <template #icon>
                <NovaIcon icon="icon-park-outline:upload-one" />
              </template>
              上传 ZIP 协议包
            </NButton>
          </NUpload>
          <NText depth="3" class="text-12px">
            上传 ZIP 文件后会自动解压到 plugin 目录，并读取 properties.json
          </NText>
        </NSpace>
      </NFormItem>

      <NFormItem label="属性管理">
        <NSpace align="center" class="w-full">
          <NTag size="large" type="success">
            {{ formData.properties?.length || 0 }} 个属性
          </NTag>
          <NButton secondary @click="openPropertyManager">
            <template #icon>
              <NovaIcon icon="icon-park-outline:setting-two" />
            </template>
            管理属性
          </NButton>
        </NSpace>
      </NFormItem>

      <NFormItem v-if="formData.properties && formData.properties.length > 0" label="属性预览">
        <div class="w-full max-h-200px flex flex-wrap gap-8px overflow-y-auto rounded-6px border border-gray-200 p-12px dark:border-gray-700">
          <NTag
            v-for="(prop, index) in formData.properties"
            :key="index"
            size="small"
            :bordered="false"
          >
            {{ prop.description }}({{ prop.name }})
          </NTag>
        </div>
      </NFormItem>
    </NForm>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="closeModal">
          取消
        </NButton>
        <NButton type="primary" @click="handleSubmit">
          {{ type === 'add' ? '添加' : '更新' }}
        </NButton>
      </NSpace>
    </template>

    <!-- 属性管理模态框 -->
    <PropertyManagerModal
      v-model:visible="propertyManagerVisible"
      :properties="formData.properties || []"
      @update:properties="handlePropertiesUpdate"
    />
  </NModal>
</template>

<style scoped></style>

